package br.com.almanach.padrao;

import java.io.Serializable;
import java.util.List;

import javax.faces.component.UICommand;
import javax.faces.event.ActionEvent;

public abstract class Consultar< T extends Serializable> {

    private List<T> lista;
    private int totalRegistros;
    private int primeiroRegistro;
    private int registrosPorPagina;
    private int totalPaginas;
    private int paginaFaixa;
    private Integer[] paginas;
    private int paginaCorrente;
    private String campoTipo;
    private boolean orderAscendente;

    public abstract List<T> getDados(int registro, int quantidade);
    public abstract int getQuantidade();

    public Consultar() {
        setRegistrosPorPagina(Configuracao.CONSULTAR_REGISTRO_POR_PAGINA);
    }

    public String pesquisar(){
        this.lista = null;
        return null;
    }

    public void primeira() {
        pagina(0);
    }

    public void proxima() {
        pagina(primeiroRegistro + registrosPorPagina);
    }

    public void anterior() {
        pagina(primeiroRegistro - registrosPorPagina);
    }

    public void ultima() {
        pagina(totalRegistros - ((totalRegistros % registrosPorPagina != 0) ? totalRegistros % registrosPorPagina : registrosPorPagina));
    }

    public void pagina(ActionEvent event) {
        pagina(((Integer) ((UICommand) event.getComponent()).getValue() - 1) * registrosPorPagina);
    }

    private void pagina(int primeiroRegistro) {
        this.primeiroRegistro = primeiroRegistro;
        abrirLista();
    }

    protected void abrirLista() {
        try{
            lista = getDados(primeiroRegistro, registrosPorPagina);
            totalRegistros = getQuantidade();
            paginaCorrente = (totalRegistros / registrosPorPagina) - ((totalRegistros - primeiroRegistro) / registrosPorPagina) + 1;
            totalPaginas = (totalRegistros / registrosPorPagina) + ((totalRegistros % registrosPorPagina != 0) ? 1 : 0);
            int paginaTamanho = Math.min(paginaFaixa, totalPaginas);
            paginas = new Integer[paginaTamanho];
            int paginaPrimeiro = Math.min(Math.max(0, paginaCorrente - (paginaFaixa / 2)), totalPaginas - paginaTamanho);
            for (int i = 0; i < paginaTamanho; i++) {
                paginas[i] = ++paginaPrimeiro;
            }
        }catch(ArithmeticException e){
        }
    }

    public List<T> getLista(){
        if (lista == null) {
            abrirLista();
        }
        return lista;
    }

    public int getTotalRegistros(){
        return totalRegistros;
    }

    public int getPrimeiroRegistro(){
        return primeiroRegistro;
    }

    public int getRegistrosPorPagina(){
        return registrosPorPagina;
    }

    public Integer[] getPaginas() {
        return paginas;
    }

    public int getPaginaCorrente() {
        return paginaCorrente;
    }

    public int getTotalPaginas(){
        return totalPaginas;
    }

    public void setRegistrosPorPagina(int registrosPorPagina){
        this.registrosPorPagina = registrosPorPagina;
    }

}